// AppConfig.java
package com.beantest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;


import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

/**
 * 应用核心配置类，整合以下功能：
 * 1. 依赖注入管理
 * 2. 外部配置加载
 * 3. 基础设施Bean定义
 * 4. 多环境适配配置
 * 5. AOP切面配置
 *
 * <p>通过 {@code @Configuration} 标识为Spring配置类，
 * 使用 {@code @PropertySource} 加载外部配置文件</p>
 *
 * @see org.springframework.context.annotation.Configuration
 */
@Configuration
@PropertySource("classpath:app.properties")
@EnableAspectJAutoProxy // 开启AOP支持
public class AppConfig {

    //----------- 生命周期控制 -----------//
    @PostConstruct
    public void init() {
        System.out.println("AppConfig 初始化完成");
    }

    @PreDestroy
    public void destroy() {
        System.out.println("AppConfig 销毁完成");
    }

    //----------- AOP切面配置 -----------//
    /**
     * 定义日志切面Bean
     * @return 日志切面实例
     */
    @Bean
    public LoggingAspect loggingAspect() {
        return new LoggingAspect();
    }

    /**
     * 审计切面（条件化注入）
     * @return 审计切面实例
     *
     * <p>激活条件：{@code audit.enabled=true}</p>
     */
    @Bean
    @ConditionalOnProperty(name = "audit.enabled", havingValue = "true")
    public AuditAspect auditAspect() {
        return new AuditAspect();
    }

    //----------- 依赖注入管理 -----------//
    private UserService userService;
    private SmsService smsService;

    /**
     * API超时配置（单位：毫秒）
     * <p>通过 {@code @Value} 注入属性值，默认值5000ms</p>
     */
    @Value("${api.timeout:5000}")
    private int apiTimeout;

    //----------- 依赖注入方法 -----------//
    /**
     * 用户服务依赖注入
     * @param userService 用户服务组件，通过类型自动装配
     */
    @Autowired
    public void setUserService(UserService userService) {
        this.userService = userService;
        System.out.println("[DI完成] UserService 已注入");
    }

    /**
     * 短信服务依赖注入
     * @param smsService 短信服务组件，通过类型自动装配
     */
    @Autowired
    public void setSmsService(SmsService smsService) {
        this.smsService = smsService;
        System.out.println("[DI完成] SmsService 已注入");
    }

    //----------- 基础设施Bean定义 -----------//
    /**
     * 定义HTTP客户端模板
     * @return 配置超时的RestTemplate实例
     *
     * <p>工厂配置说明：
     * - 连接超时时间：${api.timeout}
     * - 默认使用简单HTTP请求工厂</p>
     */
    @Bean
    public RestTemplate restTemplate() {
        SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
        factory.setConnectTimeout(apiTimeout);
        return new RestTemplate(factory);
    }

    //----------- 环境适配配置 -----------//
    /**
     * 开发环境配置标识
     * @return 开发环境配置描述
     *
     * <p>激活条件：{@code spring.profiles.active=dev}</p>
     */
    @Bean
    @Profile("dev")
    public String devEnvironmentMarker() {
        return "DEV-ENV Configuration";
    }

    /**
     * 生产环境配置标识
     * @return 生产环境配置描述
     *
     * <p>激活条件：{@code spring.profiles.active=prod}</p>
     */
    @Bean
    @Profile("prod")
    public String prodEnvironmentMarker() {
        return "PROD-ENV Configuration";
    }



    /**
     * parser.parseExpression("2 > 1 ? 'True' : 'False'")：使用SpEL进行条件判断，结果为True。
     * parser.parseExpression("10 + 20 * 2")：使用SpEL进行数学计算，结果为50。
     *
     * */

    @Bean
    public String checkCondition() {
        ExpressionParser parser = new SpelExpressionParser();

        // 示例1：条件判断
        Expression exp1 = parser.parseExpression("2 > 1 ? 'True' : 'False'");
        String result1 = exp1.getValue(String.class);
        System.out.println("Condition Result: " + result1); // 输出: True

        // 示例2：数学计算
        Expression exp2 = parser.parseExpression("10 + 20 * 2");
        int result2 = exp2.getValue(Integer.class);
        System.out.println("Calculation Result: " + result2); // 输出: 50

        return "SpEL Example";
    }



    //----------- 组合功能方法 -----------//
    /**
     * 展示当前用户配置
     * <p>依赖关系：UserService → UserRepository</p>
     */
    public void showConfig() {
        System.out.println("当前用户配置：" + userService.getUser());
    }

    /**
     * 用户配置变更通知
     * @param phone 目标手机号
     *
     * <p>操作流程：
     * 1. 获取用户信息 → 2. 发送短信通知</p>
     */
    public void notifyConfigChange(String phone) {
        String userInfo = userService.getUser();
        smsService.sendSms(phone, "配置更新通知：" + userInfo);
    }





}
